<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="UptfW" id="UptfW"><span data-lake-id="u29546b90" id="u29546b90">典型回答</span></h1>
  <p data-lake-id="ub2a5ad9c" id="ub2a5ad9c"><br></p>
  <p data-lake-id="u6e6bec6d" id="u6e6bec6d"><span data-lake-id="ucbe1bcc4" id="ucbe1bcc4">Redis中是支持事务的，他的事务主要目的是保证多个命令执行的原子性，即要在一个原子操作中执行，不会被打断。</span></p>
  <p data-lake-id="u336483ea" id="u336483ea"><span data-lake-id="ua839a44a" id="ua839a44a">​</span><br></p>
  <p data-lake-id="u45ab0fc7" id="u45ab0fc7"><span data-lake-id="u05dd8b70" id="u05dd8b70">需要注意的是，</span><strong><span data-lake-id="u931bd81e" id="u931bd81e">Redis的事务是不支持回滚的</span></strong><span data-lake-id="u8ef32fdf" id="u8ef32fdf">。从 Redis 2.6.5 开始，服务器将会在累积命令的过程中检测到错误。然后，在执行 EXEC 期间会拒绝执行事务，并返回一个错误，同时丢弃该事务。如果事务执行过程中发生错误，Redis会继续执行剩余的命令而不是回滚整个事务。</span></p>
  <p data-lake-id="u9a8084c6" id="u9a8084c6"><br></p>
  <blockquote data-lake-id="u9c5d5d4a" id="u9c5d5d4a">
   <p data-lake-id="u3ca5de2b" id="u3ca5de2b"><span data-lake-id="u7d006ef5" id="u7d006ef5">Errors happening after EXEC instead are not handled in a special way: all the other commands will be executed even if some command fails during the transaction. </span></p>
   <p data-lake-id="uc8454fcb" id="uc8454fcb"><a href="https://redis.io/docs/interact/transactions/#errors-inside-a-transaction" target="_blank" data-lake-id="u87cee92d" id="u87cee92d"><span data-lake-id="ue159a948" id="ue159a948">https://redis.io/docs/interact/transactions/#errors-inside-a-transaction</span></a></p>
  </blockquote>
  <p data-lake-id="u5e8e31b0" id="u5e8e31b0"><span data-lake-id="u0a3f9631" id="u0a3f9631">​</span><br></p>
  <p data-lake-id="u94e7393a" id="u94e7393a"><span data-lake-id="ud0e25a5b" id="ud0e25a5b">更多原子性的解释参考：</span></p>
  <p data-lake-id="u5590968b" id="u5590968b"><span data-lake-id="u5255d617" id="u5255d617">​</span><br></p>
  <p data-lake-id="u6331516f" id="u6331516f"><span data-lake-id="uaf122f4b" id="uaf122f4b">Redis事务相关的命令主要有以下几个：</span></p>
  <p data-lake-id="u8b1e0dc1" id="u8b1e0dc1"><span data-lake-id="uba60978d" id="uba60978d">​</span><br></p>
  <ul list="u78681f77">
   <li fid="ueb46566f" data-lake-id="u35856a79" id="u35856a79"><span data-lake-id="u807e1c93" id="u807e1c93">MULTI：</span><span data-lake-id="uf134e2d6" id="uf134e2d6" class="lake-fontsize-10" style="color: rgb(51, 51, 51)">标记一个事务块的开始。</span></li>
  </ul>
  <ul list="u2bd3f9b1">
   <li fid="ubd100606" data-lake-id="u5f9a2e56" id="u5f9a2e56"><span data-lake-id="u59948b50" id="u59948b50">DISCARD：</span><span data-lake-id="u5aaa166a" id="u5aaa166a" class="lake-fontsize-10" style="color: rgb(51, 51, 51)">取消事务，放弃执行事务块内的所有命令。</span></li>
  </ul>
  <ul list="u62050336">
   <li fid="u1eafee5f" data-lake-id="uaa6a3859" id="uaa6a3859"><span data-lake-id="u8f50f5c6" id="u8f50f5c6">EXEC：</span><span data-lake-id="ub0244a32" id="ub0244a32" class="lake-fontsize-10" style="color: rgb(51, 51, 51)">执行所有事务块内的命令。</span></li>
   <li fid="u1eafee5f" data-lake-id="uc65e1998" id="uc65e1998"><span data-lake-id="u95c42f76" id="u95c42f76">UNWATCH：</span><span data-lake-id="ud37fe20b" id="ud37fe20b" class="lake-fontsize-10" style="color: rgb(51, 51, 51)">取消 WATCH 命令对所有 key 的监视。</span></li>
  </ul>
  <ul list="u601b94ad">
   <li fid="u4cc43ae2" data-lake-id="u8adc8acd" id="u8adc8acd"><span data-lake-id="uac8f6820" id="uac8f6820">WATCH key [key ...]：</span><span data-lake-id="u73927c95" id="u73927c95" class="lake-fontsize-10" style="color: rgb(51, 51, 51)">监视一个(或多个) key ，如果在事务执行之前这个(或这些) key 被其他命令所改动，那么事务将被打断。</span></li>
  </ul>
  <p data-lake-id="u413c6c90" id="u413c6c90"><span data-lake-id="uf497170b" id="uf497170b" class="lake-fontsize-10" style="color: rgb(51, 51, 51)">​</span><br></p>
  <h1 data-lake-id="FaOoy" id="FaOoy"><span data-lake-id="u6e473d12" id="u6e473d12" style="color: rgb(51, 51, 51)">扩展知识</span></h1>
  <p data-lake-id="u75ac8e04" id="u75ac8e04"><br></p>
  <h2 data-lake-id="rcZCr" id="rcZCr"><span data-lake-id="u7041b165" id="u7041b165">例子</span></h2>
  <p data-lake-id="u8c6340de" id="u8c6340de"><strong><span data-lake-id="uc12cfe31" id="uc12cfe31">​</span></strong><br></p>
  <p data-lake-id="u3ef54f78" id="u3ef54f78"><span data-lake-id="u62bbf538" id="u62bbf538">下面是一个使用Jedis客户端，借助事务实现电商下单的例子：</span></p>
  <p data-lake-id="ub08fc153" id="ub08fc153"><span data-lake-id="ucc1059f4" id="ucc1059f4">​</span><br></p>
  <pre lang="java"><code>
Jedis jedis = new Jedis("localhost", 6379);

// 开启事务 ： MULTI
Transaction tx = jedis.multi();

// 扣减库存
tx.decrBy("item:10001:stock", 1);

// 计算商品总价
tx.mul(100, 2);

// 下单记录
tx.rpush("orders", "user:10001,item:10001,amount:2,total:200");

// 执行事务 ： EXEC
List&lt;Object&gt; result = tx.exec();

// 检查事务执行结果
if (result == null) {
    System.out.println("事务执行失败！");
} else {
    System.out.println("事务执行成功，订单已提交！");
}
</code></pre>
  <p data-lake-id="ue4ee1e9c" id="ue4ee1e9c"><br></p>
  <h2 data-lake-id="wVTEU" id="wVTEU"><span data-lake-id="u4aa9d655" id="u4aa9d655">事务和pipeline的区别</span></h2>
  <p data-lake-id="u8df05abb" id="u8df05abb"><br></p>
  <p data-lake-id="ud9442a80" id="ud9442a80"><br></p>
  <h2 data-lake-id="DyQyb" id="DyQyb"><span data-lake-id="u32a39f23" id="u32a39f23">事务和Lua的区别</span></h2>
  <p data-lake-id="ud73a5fed" id="ud73a5fed"><br></p>
 </body>
</html>